package gatech.cs2340.adventuretime.server;

import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.db4o.ObjectContainer;
import com.db4o.query.Predicate;


import gatech.cs2340.adventuretime.persistent.users.*;
import gatech.cs2340.adventuretime.server.*;
import gatech.cs2340.adventuretime.client.*;

public class LoginH implements RequestHandler
{
    HtmlRoutine _routine = new HtmlRoutine();

    public void processRequest(Object userNull, HttpServletRequest req,
        HttpServletResponse res, Object[] services, Object log)
        throws ServletException, IOException
    {
    	//get the outputstream, headers and menu have been added by this point
        ServletOutputStream out = res.getOutputStream();
        //get the user's attempt
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //check some easy base cases
        if(username == null || password == null||username.length()<1 ||password.length()<1)
        {
            _routine.printMsgPage(out, "User name and password are required for login.");
            return;
        }

        ObjectContainer db = (ObjectContainer)services[0];
        Client client = (Client)services[1];
        //Our query for usernames is built below in a private class, just pass it the query string itself.
		Predicate<User> query = new UsernamePredicate(username);
        try
        {
        	
        	//the db call gives us a list, since we have the addUser constraint of unique usernames, we'll only ever have one item here
        	List<User> users = db.query(query);
            User user = users.get(0);
            
            if(!user.passwordCheck(password))
            {
                _routine.printMsgPage(out, "Unable to login.");
                return;
            }
            else
            {
                HttpSession session = req.getSession(true);
                session.setAttribute("gatech.cs2340.adventuretime.persistent.users", user);
                String broadcastMsg = client.getBroadcastMsg();
                _routine.printNewsPage(out, broadcastMsg);
                return;
            }

        }
        catch(Exception e)
        {
            _routine.printMsgPage(out, "unable to login with exception: "+e.getMessage());
        }
    }
    /**
     * This is a query class wrapper. using "Search"Predicate naming pattern
     **/
    @SuppressWarnings("serial")
	private class UsernamePredicate extends Predicate<User>
    {
    	String username;
    	/**
    	 * initializes the query object
    	 * @param username this is the thing this query is build for
    	 */
    	public UsernamePredicate(String username){
    		this.username = username;
    	}
    	public boolean match(User user) {
    		
    		return this.username.equals(user.getUsername());
    	}
    	
    }
}

